/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sec_storage_ipc_stub.h"

#include <stddef.h>

#include "logger.h"
#include "module_common_ipc_stub.h"
#include "se_module_sec_storage_defines.h"
#include "sec_storage_ipc_defines.h"
#include "sec_storage_ipc_stub_inner.h"

typedef ResultCode ProcStorageStubProcess(SecStorageContext *context, SharedDataBuffer *buffer);

typedef struct StorageStubDispatch {
    uint32_t cmd;
    ProcStorageStubProcess *func;
} StorageStubDispatch;

ResultCode ProcessSecStorageCommandStub(SecStorageContext *context, uint32_t cmd, SharedDataBuffer *buffer)
{
    if (context == NULL || buffer == NULL) {
        LOG_ERROR("invalid context or shared buffer");
        return INVALID_PARA_NULL_PTR;
    }

    static const StorageStubDispatch DISPATCHS[] = {
        {CMD_SS_SET_FACTORY_RESET_AUTH_KEY, ProcStorageCmdSetFactoryResetAuthKeyStub},
        {CMD_SS_GET_FACTORY_RESET_AUTH_ALGO, ProcStorageCmdGetFactoryResetAuthKeyAlgoStub},
        {CMD_SS_PREPARE_FACTORY_REST, ProcStorageCmdPrepareFactoryResetStub},
        {CMD_SS_PROCESS_FACTORY_REST, ProcStorageCmdProcessFactoryResetStub},
        {CMD_SS_SET_TO_USER_MODE, ProcStorageCmdSetToUserModeStub},
        {CMD_SS_GET_SLOT_OPER_ALGORITHM, ProcStorageCmdGetSlotOperateAlgorithmStub},
        {CMD_SS_GET_FACTORY_RESET_ALGORITHM, ProcStorageCmdGetFactoryResetAlgorithmStub},
        {CMD_SS_GET_ALL_SLOT_SIZE, ProcStorageCmdSetAllSlotsSizeStub},
        {CMD_SS_SET_ALL_SLOT_SIZE, ProcStorageCmdSetAllSlotsSizeStub},
        {CMD_SS_ALLOCATE_SLOT, ProcStorageCmdAllocateSlotStub},
        {CMD_SS_FREE_SLOT, ProcStorageCmdFreeSlotStub},
        {CMD_SS_READ_SLOT, ProcStorageCmdReadSlotStub},
        {CMD_SS_WRITE_SLOT, ProcStorageCmdWriteSlotStub},
        {CMD_SS_GET_SLOT_STATUS, ProcStorageCmdGetSlotStatusStub},
    };

    LOG_INFO("invoked, cmd=0x%x, dSize=%u, dMaxSize=%u", cmd, buffer->dataSize, buffer->dataMaxSize);

    for (uint32_t loop = 0; loop < sizeof(DISPATCHS) / sizeof(StorageStubDispatch); loop++) {
        const StorageStubDispatch *dispatch = &DISPATCHS[loop];
        if (dispatch->cmd == cmd && dispatch->func != NULL) {
            ResultCode ret = EnableStorageScpProtocol(context);
            if (ret != SUCCESS) {
                LOG_ERROR("EnableStorageScpProtocol failed for cmd %u, ret is %u,", cmd, ret);
                return ret;
            }
            return dispatch->func(context, buffer);
        }
    }

    return ProcessSeCommonCommandStub(&context->base, cmd, buffer);
}
